home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / programm.ing / xaes_new.lzh / TREECOPY.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-04  |  7.9 KB  |  67 lines

  1. /*
  2.  * treecopy.c
  3.  *
  4.  * (c) 1994 by Thomas Binder (binder@rbg.informatik.th-darmstadt.de),
  5.  * Johann-Valentin-May-Straße 7, 64665 Alsbach-Hähnlein, Germany
  6.  *
  7.  * Modifications by Ken Hollis (khollis@chatlink.com)
  8.  *
  9.  * Contains a routine that dublicates an AES-object-tree.
  10.  *
  11.  * Permission is granted to spread this routine, but only the .c- and
  12.  * the .h-file together, *unchanged*. Permission is also granted to
  13.  * use this routine in own productions, as long as it's mentioned that
  14.  * the routine was used and that it was written by me.
  15.  *
  16.  * I can't be held responsible for the correct function of this routine,
  17.  * nor for any damage that occurs after the correct or incorrect use of
  18.  * this routine. USE IT AT YOUR OWN RISK!
  19.  *
  20.  * If you find any bugs or have suggestions, please contact me!
  21.  *
  22.  * History:
  23.  * 10/30/94: Creation
  24.  * 12/04/94: Modifications to make sure objects are complient to their
  25.  *             original object type, and verbose error message if the
  26.  *             copy didn't work.  Formatted source to look better.
  27.  */
  28.  
  29. #include "xaes.h"
  30. #include "treecopy.h"
  31.  
  32. /*
  33.  * tree_copy
  34.  *
  35.  * Copy a complete object-tree including all substructures (optional).
  36.  *
  37.  * CAUTION: The object-tree *must* have the LASTOB-flag (0x20) set in
  38.  * it's physically last member.
  39.  *
  40.  * BUG: Up to now tree_copy won't copy the color-icon-structure,
  41.  * because I'm too lazy ;) Maybe I'll do that one day. If you need it
  42.  * urgently, contact me and force me to work... Btw, this doesn't mean
  43.  * that G_CICONs won't be copied at all, but the copied tree will
  44.  * share the CICONBLKs with the original.
  45.  *
  46.  * Input:
  47.  * tree: Pointer to tree which should be copied
  48.  * what: Specifies what substructures should be copied, too (see the
  49.  *       C_xxx-definitions in tree-copy.h for details)
  50.  *
  51.  * Output:
  52.  * NULL: Tree couldn't be copied (due to lack of memory)
  53.  * otherwise: Pointer to copied tree, use free to dealloc it's memory
  54.  */
  55. OBJECT *tree_copy(OBJECT *tree, WORD what)
  56. {
  57.     WORD    i, objects;
  58.     size_t    to_malloc, size;
  59.     OBJECT    *new_tree;
  60.     char    *area;
  61.  
  62. /* Make sure that C_xxxPOINTER implies C_xxx */
  63.     if (what & C_TEDINFOPOINTER)
  64.         what |= C_TEDINFO;
  65.  
  66.     if (what & C_ICONBLKPOINTER)
  67.         what |= C_ICONBLK;
  68.  
  69.     if (what & C_BITBLKPOINTER)
  70.         what |= C_BITBLK;
  71.  
  72. /* Calculate the number of bytes we need for the new tree */
  73.     to_malloc = (size_t) 0;
  74.     for (i = 0;;) {
  75.  
  76. /* Size of the OBJECT-structure itself */
  77.         to_malloc += sizeof(OBJECT);
  78.  
  79.         switch (tree[i].ob_type & 0xff)    {
  80.             case G_TEXT:
  81.             case G_BOXTEXT:
  82.             case G_FTEXT:
  83.             case G_FBOXTEXT:
  84.                 if (what & C_TEDINFO)
  85.  
  86. /* Size of a TEDINFO-structure */
  87.                     to_malloc += sizeof(TEDINFO);
  88.  
  89.                 if (what & C_TEDINFOPOINTER) {
  90. /* Sizes of the strings in the TEDINFO-structure */
  91.                     to_malloc += (size_t)tree[i].ob_spec.tedinfo->te_txtlen;
  92.                     to_malloc += (size_t)tree[i].ob_spec.tedinfo->te_txtlen;
  93.                     to_malloc += (size_t)tree[i].ob_spec.tedinfo->te_tmplen;
  94.                 }
  95.                 break;
  96.  
  97.             case G_IMAGE:
  98.                 if (what & C_BITBLK)
  99.  
  100. /* Size of the BITBLK-structure */
  101.                     to_malloc += sizeof(BITBLK);
  102.  
  103.                 if (what & C_BITBLKPOINTER) {
  104. /* Size of the image-data in the BITBLK-structure */
  105.  
  106.                     to_malloc += (size_t)((LONG)tree[i].ob_spec.bitblk->bi_wb *
  107.                                           (LONG)tree[i].ob_spec.bitblk->bi_hl);
  108.                 }
  109.                 break;
  110.             case G_USERDEF:
  111.                 if (what & C_USERBLK)
  112.  
  113. /* Size of the USERBLK-structure */
  114.                     to_malloc += sizeof(USERBLK);
  115.                 break;
  116.  
  117.             case G_BUTTON:
  118.             case G_STRING:
  119.             case G_TITLE:
  120.                 if (what & C_TITLEBUTTONSTRING) {
  121.  
  122. /* Size of the string (with one null character at the end) */
  123.                     to_malloc += strlen(tree[i].ob_spec.free_string) + 1L;
  124.                 }
  125.                 break;
  126.  
  127.             case G_ICON:
  128.                 if (what & C_ICONBLK)
  129.  
  130. /* Size of the ICONBLK-structure */
  131.                     to_malloc += sizeof(BITBLK);
  132.  
  133.                 if (what & C_ICONBLKPOINTER) {
  134.  
  135. /* Sizes of icon-data, icon-mask and icon-text */
  136.                     to_malloc += (size_t)((LONG)tree[i].ob_spec.iconblk->ib_wicon *
  137.                                           (LONG)tree[i].ob_spec.iconblk->ib_hicon /
  138.                                                 4L + 1L + (LONG)strlen(tree[i].ob_spec.iconblk->ib_ptext));
  139.                 }
  140.                 break;
  141.         }
  142.  
  143. /* If the size is odd, make it even */
  144.         if ((LONG)to_malloc & 1)
  145.             to_malloc++;
  146.  
  147. /* Exit if we've reached the last object in the tree */
  148.         if (tree[i].ob_flags & LASTOB)
  149.             break;
  150.  
  151.         i++;
  152.     }
  153.  
  154.     objects = i + 1;
  155.  
  156. /* If there's not enough memory left for the new tree, return NULL */
  157.     if ((new_tree = (OBJECT *) malloc(to_malloc)) == NULL) {
  158.         form_alert(1, "[3][Sorry, there is no available|memory for this copy!][ OK ]");
  159.         return(NULL);
  160.     }
  161.  
  162. /*
  163.  * area contains a pointer to the area where we copy the structures to
  164.  */
  165.     area = (char *)((LONG)new_tree + (LONG)objects * (LONG)sizeof(OBJECT));
  166.  
  167.     for (i = 0; i < objects; i++) {
  168.  
  169. /* Copy the contents of the OBJECT-structure */
  170.         new_tree[i] = tree[i];
  171.  
  172. /* This was added to assure true copies of the object type */
  173.         new_tree[i].ob_type = tree[i].ob_type;
  174.  
  175.         switch (tree[i].ob_type & 0xff) {
  176.             case G_TEXT:
  177.             case G_BOXTEXT:
  178.             case G_FTEXT:
  179.             case G_FBOXTEXT:
  180.                 if (what & C_TEDINFO) {
  181.  
  182. /* Copy the contents of the TEDINFO-structure */
  183.                     *(TEDINFO *)area = *tree[i].ob_spec.tedinfo;
  184.                     new_tree[i].ob_spec.tedinfo = (TEDINFO *)area;
  185.                     area += sizeof(TEDINFO);
  186.                 }
  187.  
  188.                 if (what & C_TEDINFOPOINTER) {
  189.  
  190. /* Copy the strings in the TEDINFO-structure */
  191.                     strncpy(area, tree[i].ob_spec.tedinfo->te_ptext, tree[i].ob_spec.tedinfo->te_txtlen);
  192.                     new_tree[i].ob_spec.tedinfo->te_ptext = area;
  193.                     area += tree[i].ob_spec.tedinfo->te_txtlen;
  194.                     strncpy(area, tree[i].ob_spec.tedinfo->te_ptmplt, tree[i].ob_spec.tedinfo->te_tmplen);
  195.                     new_tree[i].ob_spec.tedinfo->te_ptmplt = area;
  196.                     area += tree[i].ob_spec.tedinfo->te_tmplen;
  197.                     strncpy(area, tree[i].ob_spec.tedinfo->te_pvalid, tree[i].ob_spec.tedinfo->te_txtlen);
  198.                     new_tree[i].ob_spec.tedinfo->te_pvalid = area;
  199.                     area += tree[i].ob_spec.tedinfo->te_txtlen;
  200.                 }
  201.                 break;
  202.  
  203.             case G_IMAGE:
  204.                 if (what & C_BITBLK) {
  205.  
  206. /* Copy the contents of the BITBLK-structure */
  207.                     *(BITBLK *)area = *tree[i].ob_spec.bitblk;
  208.                     new_tree[i].ob_spec.bitblk = (BITBLK *)area;
  209.                     area += sizeof(BITBLK);
  210.                 }
  211.  
  212.                 if (what & C_BITBLKPOINTER) {
  213.  
  214. /* Copy the image-data */
  215.                     size = (size_t)((LONG)tree[i].ob_spec.bitblk->bi_wb *
  216.                                      (LONG)tree[i].ob_spec.bitblk->bi_hl);
  217.                     memcpy(area, tree[i].ob_spec.bitblk->bi_pdata, size);
  218.                     new_tree[i].ob_spec.bitblk->bi_pdata = (WORD *)area;
  219.                     area += size;
  220.                 }
  221.                 break;
  222.  
  223.             case G_USERDEF:
  224.                 if (what & C_USERBLK) {
  225.  
  226. /* Copy the contents of the USERBLK-structure */
  227.                     *(USERBLK *)area = *tree[i].ob_spec.userblk;
  228.                     new_tree[i].ob_spec.userblk = (USERBLK *)area;
  229.                     area += sizeof(USERBLK);
  230.                 }
  231.                 break;
  232.  
  233.             case G_BUTTON:
  234.             case G_STRING:
  235.             case G_TITLE:
  236.                 if (what & C_TITLEBUTTONSTRING) {
  237.  
  238. /* Copy the string */
  239.                     size = strlen(tree[i].ob_spec.free_string) + 1L;
  240.                     strcpy(area, tree[i].ob_spec.free_string);
  241.                     new_tree[i].ob_spec.free_string = area;
  242.                     area += size;
  243.                 }
  244.                 break;
  245.  
  246.             case G_ICON:
  247.                 if (what & C_ICONBLK) {
  248.  
  249. /* Copy the contents of the ICONBLK-structure */
  250.                     *(ICONBLK *)area = *tree[i].ob_spec.iconblk;
  251.                     new_tree[i].ob_spec.iconblk = (ICONBLK *)area;
  252.                     area += sizeof(ICONBLK);
  253.                 }
  254.  
  255.                 if (what & C_ICONBLKPOINTER) {
  256.                     size = (size_t)((LONG)tree[i].ob_spec.iconblk->ib_wicon *
  257.                                     (LONG)tree[i].ob_spec.iconblk->ib_hicon /
  258.                                     8L);
  259. /* Copy the mask-data */
  260.                     memcpy(area, tree[i].ob_spec.iconblk->ib_pmask, size);
  261.                     new_tree[i].ob_spec.iconblk->ib_pmask =    (WORD *)area;
  262.                     area += size;
  263.  
  264. /* Copy the icon-data */
  265.                     memcpy(area, tree[i].ob_spec.iconblk->ib_pdata, size);
  266.                     new_tree[i].ob_spec.iconblk->ib_pdata = (WORD *)area;
  267.                     area += size;
  268.                     size = strlen(tree[i].ob_spec.iconblk->ib_ptext) + 1L;
  269.  
  270. /* Copy the icon-string */
  271.                     strcpy(area, tree[i].ob_spec.iconblk->ib_ptext);
  272.                     new_tree[i].ob_spec.iconblk->ib_ptext = area;
  273.                     area += size;
  274.                 }
  275.                 break;
  276.         }
  277.  
  278. /* Assure that area contains an even address */
  279.         if ((LONG)area & 1)
  280.             area++;
  281.     }
  282.  
  283.     return(new_tree);
  284. }
  285.  
  286. /* EOF */
  287.